/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package gmovil_jpa.controladores;

import gmovil_jpa.controladores.exceptions.IllegalOrphanException;
import gmovil_jpa.controladores.exceptions.NonexistentEntityException;
import gmovil_jpa.entidades.PuntoVenta;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import gmovil_jpa.entidades.AgenciaComercial;
import gmovil_jpa.entidades.Factura;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author castlerock
 */
public class PuntoVentaJpaController {

    public PuntoVentaJpaController() {
        emf = Persistence.createEntityManagerFactory("gmovil_jpaPU");
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(PuntoVenta puntoVenta) {
        if (puntoVenta.getFacturaList() == null) {
            puntoVenta.setFacturaList(new ArrayList<Factura>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            AgenciaComercial agenciaComercial = puntoVenta.getAgenciaComercial();
            if (agenciaComercial != null) {
                agenciaComercial = em.getReference(agenciaComercial.getClass(), agenciaComercial.getIdAgenciaComercial());
                puntoVenta.setAgenciaComercial(agenciaComercial);
            }
            List<Factura> attachedFacturaList = new ArrayList<Factura>();
            for (Factura facturaListFacturaToAttach : puntoVenta.getFacturaList()) {
                facturaListFacturaToAttach = em.getReference(facturaListFacturaToAttach.getClass(), facturaListFacturaToAttach.getIdFactura());
                attachedFacturaList.add(facturaListFacturaToAttach);
            }
            puntoVenta.setFacturaList(attachedFacturaList);
            em.persist(puntoVenta);
            if (agenciaComercial != null) {
                agenciaComercial.getPuntoVentaList().add(puntoVenta);
                agenciaComercial = em.merge(agenciaComercial);
            }
            for (Factura facturaListFactura : puntoVenta.getFacturaList()) {
                PuntoVenta oldPuntoVentaOfFacturaListFactura = facturaListFactura.getPuntoVenta();
                facturaListFactura.setPuntoVenta(puntoVenta);
                facturaListFactura = em.merge(facturaListFactura);
                if (oldPuntoVentaOfFacturaListFactura != null) {
                    oldPuntoVentaOfFacturaListFactura.getFacturaList().remove(facturaListFactura);
                    oldPuntoVentaOfFacturaListFactura = em.merge(oldPuntoVentaOfFacturaListFactura);
                }
            }
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(PuntoVenta puntoVenta) throws IllegalOrphanException, NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            PuntoVenta persistentPuntoVenta = em.find(PuntoVenta.class, puntoVenta.getIdPuntoVenta());
            AgenciaComercial agenciaComercialOld = persistentPuntoVenta.getAgenciaComercial();
            AgenciaComercial agenciaComercialNew = puntoVenta.getAgenciaComercial();
            List<Factura> facturaListOld = persistentPuntoVenta.getFacturaList();
            List<Factura> facturaListNew = puntoVenta.getFacturaList();
            List<String> illegalOrphanMessages = null;
            for (Factura facturaListOldFactura : facturaListOld) {
                if (!facturaListNew.contains(facturaListOldFactura)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain Factura " + facturaListOldFactura + " since its puntoVenta field is not nullable.");
                }
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            if (agenciaComercialNew != null) {
                agenciaComercialNew = em.getReference(agenciaComercialNew.getClass(), agenciaComercialNew.getIdAgenciaComercial());
                puntoVenta.setAgenciaComercial(agenciaComercialNew);
            }
            List<Factura> attachedFacturaListNew = new ArrayList<Factura>();
            for (Factura facturaListNewFacturaToAttach : facturaListNew) {
                facturaListNewFacturaToAttach = em.getReference(facturaListNewFacturaToAttach.getClass(), facturaListNewFacturaToAttach.getIdFactura());
                attachedFacturaListNew.add(facturaListNewFacturaToAttach);
            }
            facturaListNew = attachedFacturaListNew;
            puntoVenta.setFacturaList(facturaListNew);
            puntoVenta = em.merge(puntoVenta);
            if (agenciaComercialOld != null && !agenciaComercialOld.equals(agenciaComercialNew)) {
                agenciaComercialOld.getPuntoVentaList().remove(puntoVenta);
                agenciaComercialOld = em.merge(agenciaComercialOld);
            }
            if (agenciaComercialNew != null && !agenciaComercialNew.equals(agenciaComercialOld)) {
                agenciaComercialNew.getPuntoVentaList().add(puntoVenta);
                agenciaComercialNew = em.merge(agenciaComercialNew);
            }
            for (Factura facturaListNewFactura : facturaListNew) {
                if (!facturaListOld.contains(facturaListNewFactura)) {
                    PuntoVenta oldPuntoVentaOfFacturaListNewFactura = facturaListNewFactura.getPuntoVenta();
                    facturaListNewFactura.setPuntoVenta(puntoVenta);
                    facturaListNewFactura = em.merge(facturaListNewFactura);
                    if (oldPuntoVentaOfFacturaListNewFactura != null && !oldPuntoVentaOfFacturaListNewFactura.equals(puntoVenta)) {
                        oldPuntoVentaOfFacturaListNewFactura.getFacturaList().remove(facturaListNewFactura);
                        oldPuntoVentaOfFacturaListNewFactura = em.merge(oldPuntoVentaOfFacturaListNewFactura);
                    }
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Integer id = puntoVenta.getIdPuntoVenta();
                if (findPuntoVenta(id) == null) {
                    throw new NonexistentEntityException("The puntoVenta with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Integer id) throws IllegalOrphanException, NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            PuntoVenta puntoVenta;
            try {
                puntoVenta = em.getReference(PuntoVenta.class, id);
                puntoVenta.getIdPuntoVenta();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The puntoVenta with id " + id + " no longer exists.", enfe);
            }
            List<String> illegalOrphanMessages = null;
            List<Factura> facturaListOrphanCheck = puntoVenta.getFacturaList();
            for (Factura facturaListOrphanCheckFactura : facturaListOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This PuntoVenta (" + puntoVenta + ") cannot be destroyed since the Factura " + facturaListOrphanCheckFactura + " in its facturaList field has a non-nullable puntoVenta field.");
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            AgenciaComercial agenciaComercial = puntoVenta.getAgenciaComercial();
            if (agenciaComercial != null) {
                agenciaComercial.getPuntoVentaList().remove(puntoVenta);
                agenciaComercial = em.merge(agenciaComercial);
            }
            em.remove(puntoVenta);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<PuntoVenta> findPuntoVentaEntities() {
        return findPuntoVentaEntities(true, -1, -1);
    }

    public List<PuntoVenta> findPuntoVentaEntities(int maxResults, int firstResult) {
        return findPuntoVentaEntities(false, maxResults, firstResult);
    }

    private List<PuntoVenta> findPuntoVentaEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(PuntoVenta.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public PuntoVenta findPuntoVenta(Integer id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(PuntoVenta.class, id);
        } finally {
            em.close();
        }
    }

    public int getPuntoVentaCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<PuntoVenta> rt = cq.from(PuntoVenta.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }

}
